using System;
using System.Collections.Generic;
using System.Text;
using Dracham.Classes;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Dracham.TileManagement.CharacterManagement.Animation;
using Dracham.Network;

namespace Dracham.TileManagement.CharacterManagement
{
    public class Player
    {
        #region player props 

        private String name;

        public String Name
        {
            get { return name; }
            set { name = value; }
        }
        private Int32 maxHitPoints;

        public Int32 MaxHitPoints
        {
            get { return maxHitPoints; }
            set { maxHitPoints = value; }
        }

        private Int32 currentHitpoints;

        public Int32 CurrentHitpoints
        {
            get { return currentHitpoints; }
            set { currentHitpoints = value; }
        }

        #endregion

        private Position position;
        private Model model;
        private Int32 speed = 500;

        private static readonly Int32 renderX = (Dracham.TileWidth * 8) + Dracham.TileWidth * ((Dracham.Width / 2) - 0);
        private static readonly Int32 renderY = (Dracham.TileHeight * 0) + Dracham.TileHeight * ((Dracham.Height / 2) - 0);

        public static Int32 RenderX
        {
            get { return Player.renderX; }
        }

        public static Int32 RenderY
        {
            get { return Player.renderY; }
        }

        private ZoneTile currentZoneObject;
        public ZoneTile CurrentZoneObject
        {
            get
            {
                return this.currentZoneObject;
            }
            set
            {
                if (value != currentZoneObject)
                {
                    if (currentZoneObject != null)
                        currentZoneObject.OnLeave();

                    currentZoneObject = value;
                    currentZoneObject.OnEnter();
                }
            }
        }

        public Model Model
        {
            get { return model; }
            set { model = value; }
        }

        public Position Position
        {
            get { return this.position; }
            set { this.position = value; Dracham.CurrentZone = value.Zone; }
        }

        public Player(Model model)
        {
            this.model = model;
            this.image = model.GetWalkByDirection(WalkDirection.Right.ToString()).Image;
        }

        #region movement & rendering 

        private Int32 lastMove;
        private WalkDirection move = WalkDirection.None;
        private Image image;
        private enum WalkDirection
        {
            Up,
            Left,
            Right,
            Down,
            None
        }

        public void Update(GameTime gameTime)
        {
            if (move != WalkDirection.None)
            {
                this.lastMove += (Int32)gameTime.ElapsedGameTime.TotalMilliseconds;
                model.GetWalkByDirection(move.ToString()).Update(gameTime);
                this.image = model.GetWalkByDirection(move.ToString()).Image;

                if (move == WalkDirection.Right)
                {
                    this.position.TileX = 0 - (Int32)(Dracham.TileWidth * ((float)lastMove / this.speed));
                    if (lastMove > this.model.MoveSpeed)
                    {
                        this.position.MapX++;
                        this.position.TileX = 0;
                        move = WalkDirection.None;
                    }
                }
                else if (move == WalkDirection.Left)
                {
                    this.position.TileX = (Int32)(Dracham.TileWidth * ((float)lastMove / this.speed));

                    if (lastMove > this.model.MoveSpeed)
                    {
                        this.position.MapX--;
                        this.position.TileX = 0;
                        move = WalkDirection.None;
                    }
                }
                else if (move == WalkDirection.Up)
                {
                    this.position.TileY = (Int32)(Dracham.TileHeight * ((float)lastMove / this.speed));

                    if (lastMove > this.model.MoveSpeed)
                    {
                        this.position.MapY--;
                        this.position.TileY = 0;
                        move = WalkDirection.None;
                    }
                }
                else if (move == WalkDirection.Down)
                {
                    this.position.TileY = 0 - (Int32)(Dracham.TileHeight * ((float)lastMove / this.speed));

                    if (lastMove > this.model.MoveSpeed)
                    {
                        this.position.MapY++;
                        this.position.TileY = 0;
                        move = WalkDirection.None;
                    }
                }

                if (move == WalkDirection.None)
                    lastMove = 0;

                return;
            }

            Int32 newX = 0;
            Int32 newY = 0;
            if (Keyboard.GetState().IsKeyDown(Keys.Right))
            {
                newX = position.MapX + 1;
                newY = position.MapY;

                move = WalkDirection.Right;
            }

            if (Keyboard.GetState().IsKeyDown(Keys.Left))
            {
                newX = position.MapX - 1;
                newY = position.MapY;

                move = WalkDirection.Left;
            }

            if (Keyboard.GetState().IsKeyDown(Keys.Up))
            {
                newX = position.MapX;
                newY = position.MapY - 1;

                move = WalkDirection.Up;
            }

            if (Keyboard.GetState().IsKeyDown(Keys.Down))
            {
                newX = position.MapX;
                newY = position.MapY + 1;

                move = WalkDirection.Down;
            }

            if (move != WalkDirection.None)
            {
                if (!position.Zone.IsCollision(newX, newY))
                {
                    Dracham.DrachamNetwork.Invoke(RequestType.CharacterMovement,
                        new NetworkParameter(Dracham.SessionKey, 36),
                        new NetworkParameter(Position.Zone.ZoneId, 20),
                        new NetworkParameter(newX, 5),
                        new NetworkParameter(newY, 5));
                }
                else { move = WalkDirection.None; }
            }
        }

        public void Render(GameTime time, SpriteBatch sb)
        {
            sb.Draw(
                this.model.Texture,
                new Microsoft.Xna.Framework.Rectangle(renderX, renderY, Dracham.TileWidth, Dracham.TileHeight),
                new Microsoft.Xna.Framework.Rectangle((image.X * Dracham.TileWidth), (image.Y * Dracham.TileHeight), Dracham.TileWidth, Dracham.TileHeight),
                Color.White
            );
        }

        #endregion

        public void Attack(MobileObject mobileObject)
        {
            Dracham.DrachamNetwork.Invoke(RequestType.AttackRequest,
                new NetworkParameter(Dracham.SessionKey, 36),
                new NetworkParameter(1, 5),
                new NetworkParameter(mobileObject.MobId, 36));
        }
    }
}
